home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MEMORY.SWG / 0037_Driver Memory Size.pas < prev    next >
Pascal/Delphi Source File  |  1994-01-27  |  4KB  |  96 lines

  1. {
  2. │>anybody know how I can determine the size of the driver in
  3. │>memory?
  4. │ I would assume they take the Drivers name and search through the
  5. │ Memory Control Blocks maintained by DOS and seeing if the driver
  6. │ owns any of them.  But there might be an easier way.
  7.  
  8. There is.  An undocumented DOS function (52h) gives you the "list of
  9. lists", which contains the first device driver in a linked list, which
  10. you can then traverse.  (See Schulman's _Undocumented DOS_.)
  11.  
  12. Take the address of the device driver header, and look at the 0 offset
  13. in the "segment" which is 1 segment address unit before the beginning
  14. of the device driver header.  For example, if the device driver header
  15. is at $1234:$0000, look at address $1233:0.  If the byte at that
  16. address is "M", "Z", or "D", we have either a valid memory control
  17. block header ("M" or "Z"), or a "device driver subheader" ("D") which
  18. follows the same format.  In either case, the word at <segment>:0003
  19. gives the number of 16-byte paragraphs used by that memory block;
  20. multiply by 16 to get the size in bytes.  The following TP code should
  21. illustrate this (*only* HexW is used from OPString; substitute your
  22. own or any PD/Shareware hex conversion routine if you don't have OPro):
  23. }
  24.  
  25. USES DOS, OPString;
  26. TYPE
  27.   PMCBhdr = ^TMCBhdr;
  28.   TMCBhdr = RECORD
  29.     Signature: CHAR;  { 'M', 'Z', or one of the valid 'subblock' letters}
  30.     OwnerSeg:  WORD;  { Segment of "owner" of this block }
  31.     SizeParas: WORD;  { Size of block, in 16-byte paragraphs }
  32.     Unused:    ARRAY [1..3] OF CHAR;
  33.     Name:      ARRAY [1..8] OF CHAR; {Name of owner program (DOS 4+)}
  34.   END;
  35.   PDevHdr = ^TDevHdr;
  36.   TDevHdr = RECORD
  37.     NextDriver: POINTER;              { Next driver in device chain }
  38.     Attr:       WORD;                 { Driver attribute word }
  39.     Strategy:   WORD;                 { Offset within this segment }
  40.     Interrupt:  WORD;                 {   of the driver strategy & }
  41.                                       {   interrupt routines.      }
  42.     Name:       ARRAY [1..8] OF CHAR; { Device name for char devs; }
  43.                  {   for block devices, first byte is # of logical }
  44.                  {   devices associated with this driver, others   }
  45.                  {   are unused.                                   }
  46.   END;
  47.  
  48. PROCEDURE DisplayDeviceHeader( DevHdr: PDevHdr );
  49.   VAR
  50.     MCBptr: ^TMCBhdr;
  51.     Size:   LONGINT;
  52.   BEGIN
  53.     { The line to be displayed will look something like this:      }
  54.     { ssss:oooo dev_name mem_size owner_name                       }
  55.     { The last two columns are displayed only under DOS 4+, and    }
  56.     { only when the information is found -- may fail under 386^Max }
  57.     Write( HexW( Seg( DevHdr^ ) ), ':', HexW( Ofs( DevHdr^ ) ), ' ' );
  58.  
  59.     { See if it's a character device.  If it is, then it has a name }
  60.     { to display.                                                   }
  61.     IF (DevHdr^.Attr AND $8000) <> 0 THEN
  62.       Write( DevHdr^.Name:12, ' ' )
  63.     ELSE  { Block device -- write # of logical drives }
  64.       Write( Ord( DevHdr^.Name[1] ):3, ' drive(s) ' );
  65.  
  66.     { See if the DOS version supports the 'sub-MCBs' introduced for }
  67.     { device drivers in the first MCB in DOS version 4, and/or the  }
  68.     { Name field in the MCB introduced in v4.                       }
  69.     IF Lo( DosVersion ) >= 4 THEN BEGIN
  70.       MCBptr := Ptr( Seg( DevHdr^ ) - 1, 0 );
  71.  
  72.       { Check for MCB sig., and make sure the MCB "owns itself" }
  73.       IF (MCBptr^.Signature IN ['M', 'Z', 'D']) AND
  74.          (MCBptr^.OwnerSeg = Seg( DevHdr^ ) ) THEN BEGIN
  75.         Size := MCBptr^.SizeParas * 16;
  76.         Write( Size:6, MCBptr^.Name:9 );
  77.       END; { IF MCB signature }
  78.     END; { IF DosVersion }
  79.     WriteLn;
  80.   END; {DisplayDeviceHeader}
  81.  
  82. VAR
  83.   Regs: REGISTERS;  CurDevice: PDevHdr;
  84. BEGIN { main program }
  85.   Regs.AH := $52;
  86.   MSDos( Regs );
  87.   IF Lo( DosVersion ) < 3 THEN                { Get first device in list; }
  88.     CurDevice := Ptr( Regs.ES, Regs.BX+$17 )  { location varies by DOS    }
  89.   ELSE                                        { version.                  }
  90.     CurDevice := Ptr( Regs.ES, Regs.BX+$22 );
  91.   REPEAT
  92.     DisplayDeviceHeader( CurDevice );
  93.     CurDevice := CurDevice^.NextDriver;
  94.   UNTIL Ofs( CurDevice^ ) = $FFFF;
  95. END.
  96.